/*********************************** (C) COPYRIGHT ******************************
 * address: https://gitee.com/liuniansihuo/multitasks-os
 *
 * Change Logs:
 * Date			Author      	Notes
 * 2019-06-29	LiuHuo			first version
 *
 * Modify Note:  该文件为定时器任务执行功能。
    即从设置后开始计时，到达时间后，执行次数为0后，然后删除任务。
*******************************************************************************/
#include "Typedef.h"

#include "os_tick.h"
#include "timer.h"


static struct list_head timer_list_head=LIST_HEAD_INTT(timer_list_head);
static SysTick_t timer_Tick=0;

/*
* function:初始化定时器任务结构为空
* param:
	timer:结构体指针
* return:
*/
void init_timer(struct timer_list * timer)
{
	list_init(&(timer->entry));
	timer->expires  = 0;
    timer->time     = 0;
    timer->count    = 0;
	timer->function = (void*)0;
	timer->data     = 0;
}
/*
* function:设置定时任务结构
* param:
	timer:结构体指针
	function:定时任务执行函数
	data:定时任务函数参数
	expires:任务定时执行时间间隔
* return:
*/
void setup_timer(struct timer_list * timer,void (*function)(unsigned long data), unsigned long data,unsigned long time,unsigned long count)
{
	list_init(&(timer->entry));
	timer->expires  = time;
    timer->time     = time;
    timer->count    = count;
	timer->function = function;
	timer->data     = data;
}
/*
* function:添加定时任务到定时器双链表中
* param:
	timer:结构体指针
* return:
*/
void add_timer(struct timer_list * timer)
{
	list_add_tail(&(timer->entry), &timer_list_head);
}
/*
* function:设置定时任务结构并添加定时任务到定时器双链表中
* param:
	timer:结构体指针
	function:定时任务执行函数
	data:定时任务函数参数
	expires:任务定时执行时间间隔
* return:
*/
void setup_add_timer(struct timer_list * timer,void (*function)(unsigned long data), unsigned long data,unsigned long time,unsigned long count)
{
	setup_timer( timer,function, data,time,count);
	list_add_tail(&(timer->entry), &timer_list_head);
}
/*
* function:从定时器双链表中删除指定定时器任务
* param:
	timer:结构体指针
* return:
*/
void del_timer(struct timer_list * timer)
{
	list_del_init(&(timer->entry));
}
/*
* function:修改定时器任务执行时间间隔
* param:
	timer:结构体指针
	expires：新时间间隔
* return:
*/
void mod_timer(struct timer_list * timer, unsigned long time)
{
	del_timer(timer);
	timer->time = time;
	add_timer(timer);
}
/*
* function:定时器任务是否挂起
* param:
	timer:结构体指
* return:1：挂起  0：非挂起
*/
int timer_pending(const struct timer_list * timer)
{
	return (timer->entry.next == &timer->entry);
}
/*
* function:删除所有定时器任务
* param:
* return:
*/
void del_all_timer(void)
{
	struct timer_list * pos;
	struct timer_list * n;
	list_for_each_entry_safe(pos,n, &timer_list_head, entry)
	{
		list_del_init(&pos->entry);
	}
}
/*
* function:定时器任务总执行，在主循环中执行
* param:
* return:
*/

void run_timer(void)
{
	unsigned long diff = systick_get_time_difference(timer_Tick);
	struct timer_list * pos;
	struct timer_list * n;

	if(diff == 0)// >= 1ms
		return;

	timer_Tick = systick_get_currTime();
	list_for_each_entry_safe(pos,n, &timer_list_head, entry)
	{
		if(pos->expires<=diff)
		{
            if(pos->function)
                pos->function(pos->data);

            pos->count--;
            if(0==pos->count)// 循环次数为0，即结束
            {
                list_del_init(&pos->entry);//从链表中删除
                pos->expires    = 0x0ul;//使用后清除
                pos->time       = 0x0ul;
                pos->function   = NULL;//使用后清除
            }
            else
                pos->expires    = pos->time;//使用后清除
		}
		else
			pos->expires -= diff;
	}
}

#define Timer_Size_Max	32
static struct timer_list timers[Timer_Size_Max]={{.count=0}};

static struct timer_list * timer_item_get(void)
{
	for(int i=0; i<Timer_Size_Max; i++)
	{
		if((0 == timers[i].time) && (0 == timers[i].count) && (NULL == timers[i].function))//找未使用的timer结构
		{
			return &timers[i];
		}
	}
	return NULL;
}

unsigned char timer_item_add(void (*function)(unsigned long data), unsigned long data,unsigned long time,unsigned long count)
{
	struct timer_list * p = timer_item_get();

	if((NULL==p) || (NULL==function) || (0==count) || (0==time))
		return 1;

	setup_add_timer(p, function, data, time,count);
	return 0;
}

